package org.uim.cricket.storage;

import java.util.List;
import java.util.Map;

import org.uim.cricket.entities.MatchPlayer;
import org.uim.cricket.entities.aggr.SingleInning;
import org.uim.cricket.entities.match.CricketMatch;
import org.uim.cricket.storage.queries.*;

public class DBExecutor {

	private Storage storage = null;
	private QueryAppendable appender = null;
	
	public DBExecutor(Storage theStorage, QueryAppendable appendable) {
		this.storage = theStorage;
		this.appender = appendable;
	}
	
	public void execute() throws Exception {
		if (this.storage == null) 
			throw new Exception ("Match or players objects can't be null!");
		if (this.appender == null)
			throw new Exception("Query Appender can't be null!");
		
		CricketMatch match = this.storage.getMatch();
		Map<String, List<MatchPlayer>> players = this.storage.getPlayers();
		
		this.appender.open();
		
		if (match != null) {
			this.appender.doAppend("----- Match: " + match.getId().getPrefix() + "#" + match.getId().getInternationalID());
			this.appender.doAppend("--------\n");
			this.appender.flush();
		}

		PreProtocolDBExecutor preDb = new PreProtocolDBExecutor(storage);
		StringBuilder query = preDb.execute();
		
		this.appender.doAppend(query.toString());
		this.appender.flush();
		
		
		if (match != null) this.insertMatch(match);
		if (players != null) this.insertPlayers(match, players);
		
		this.appender.close();
	}
	
	private void insertMatch(CricketMatch match) throws Exception {
		String query = new MatchQueryGenerator(match).generateQuery();
		this.appender.doAppend(query);
		
		SingleInning[] inns = match.getInnings();
		if (inns != null) {
			for (int i=0; i<inns.length; i++) {
				query = new SingleInningQueryGenerator(match, inns[i]).generateQuery();
				this.appender.doAppend(query);
			}
		}
		
		this.appender.flush();
	}
	
	private void insertPlayers(CricketMatch match, Map<String, List<MatchPlayer>> players) throws Exception {
		
		for (String team : players.keySet()) {
			List<MatchPlayer> tplayers = players.get(team);
			if (tplayers == null) continue;
			
			for (int p=0; p<tplayers.size(); p++) {
				MatchPlayer mp = tplayers.get(p);
				if (mp == null) continue;
				
				String query = new SinglePlayerQueryGenerator(match, team, mp).generateQuery();
				this.appender.doAppend(query);
			}
			
		}
		
	}
	
	public void setStorage(Storage storage) {
		this.storage = storage;
	}
	
	public Storage getStorage() {
		return storage;
	}
	
}
